package com.sz.biz.logistics.ord.service.impl;

import com.google.common.collect.Lists;
import com.sz.biz.common.constants.CommCodes;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.logistics.core.service.ProductService;
import com.sz.biz.logistics.ord.dto.OrdOrderCargoDto;
import com.sz.biz.logistics.ord.entity.OrdOrderCargo;
import com.sz.biz.logistics.ord.service.OrdOrderCargoService;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.system.service.SysDictService;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Function: 产品订单的明细 <br>
 * Author: hpeng.wang. <br>
 * Date: 2017-03-31 13:52:00.
 */
@Service("ordOrderCargoService")
public class OrdOrderCargoServiceImpl extends AbstractService implements OrdOrderCargoService {
    @Override
    protected String getMapperNamespace() {
        return "com.sz.biz.logistics.ord.entity.mapper.OrdOrderCargoMapper";
    }

    @Autowired
    private SysDictService dictService;
    @Autowired
    private ProductService productService;

    @Override
    public int save(OrdOrderCargo entry) {
        dao.save(getSqlName("insertSelective"), entry);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_ORDER_CARGO", entry);
        PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.ADD, "添加订单明细", dataBackup);
        return entry.getId();
    }

    @Override
    public void batchSave(List<OrdOrderCargo> list) {
        if (!CollectionUtils.isEmpty(list)) {
            dao.batchInsert(getSqlName("insert"), list);
            //保存操作日志
            Map<String, Object> dataBackup = new HashMap<>();
            dataBackup.put("ADD_ORDER_CARGO", list);
            PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.ADD, "添加订单明细", dataBackup);
        }
    }

    @Override
    public int delete(Integer id) {
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_ORDER_CARGO", id);
        PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.DELETE, "删除订单明细", dataBackup);
        return (int) dao.update(getSqlName("deleteByPrimaryKey"), id);
    }

    @Override
    public void batchdelete(List<Integer> ids) {
        dao.batchUpdate(getSqlName("deleteByPrimaryKey"), ids);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_ORDER_CARGO", ids);
        PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.DELETE, "删除订单明细", dataBackup);
    }

    @Override
    public void deleteByOrderNo(String orderNo) {
        if (StringUtils.hasLength(orderNo)) {
            dao.delete(getSqlName("deleteByOrderNo"), orderNo);
            //保存操作日志
            Map<String, Object> dataBackup = new HashMap<>();
            dataBackup.put("DELETE_ORDER_CARGO", orderNo);
            PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.DELETE, "通过orderNo删除订单明细", dataBackup);
        }
    }

    @Override
    public void batchUpdate(List<OrdOrderCargo> list) {
        dao.batchUpdate(getSqlName("updateById"), list);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_ORDER_CARGO", list);
        PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.UPDATE, "修改订单明细", dataBackup);
    }

    @Override
    public void batchUpdateByOrderNo(List<OrdOrderCargo> list) {
        dao.batchUpdate(getSqlName("batchUpdateByOrderNo"), list);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_ORDER_CARGO", list);
        PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.UPDATE, "修改订单明细", dataBackup);
    }

    @Override
    public int update(OrdOrderCargo entry) {
        int flag = (int) dao.update(getSqlName("updateById"), entry);
        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_ORDER_CARGO", entry);
        PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_ORDER_CARGO, UserActions.UPDATE, "修改订单明细", dataBackup);
        return flag;
    }

    @Override
    public OrdOrderCargo findById(Integer id) {
        ParamData pd = new ParamData();
        pd.put("id", id);
        OrdOrderCargo entry = (OrdOrderCargo) dao.findForObject(getSqlName("findById"), pd);
        return entry;
    }

    @Override
    public List<OrdOrderCargo> findByIds(List<Integer> ids) {
        if (ids == null || ids.size() <= 0) {
            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY);
        }
        ParamData pd = new ParamData();
        pd.put("ids", ids);
        List<OrdOrderCargo> list = dao.findForList(getSqlName("findByIds"), pd, OrdOrderCargo.class);
        return list;
    }

    @Override
    public List<OrdOrderCargo> findByOrderNos(List<String> OrderNos) {
        if (OrderNos == null || OrderNos.size() <= 0) {
            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY);
        }
        ParamData pd = new ParamData();
        pd.put("orderNos", OrderNos);
        List<OrdOrderCargo> list = dao.findForList(getSqlName("findByOrderNos"), pd, OrdOrderCargo.class);
        return list;
    }

    @Override
    public QResultDto findByParam(QueryParams params) {
        ParamData pd = this.convertQueryParams(params);
        pd.put("language", PrincipalUtils.getLocalLanguage());
        List<Map> list = dao.findForList(getSqlName("findByParamListPage"), pd, Map.class);
        return new QResultDto(list, pd.getPagination());
    }

    @Override
    public List<OrdOrderCargo> findByOrderNo(String orderNo) {
        List<OrdOrderCargo> orderCargoList = new ArrayList<>();
        if (StringUtils.hasLength(orderNo)) {
            orderCargoList = dao.findForList(getSqlName("findByOrderNo"), orderNo, OrdOrderCargo.class);
        }
        return orderCargoList;
    }

    @Override
    public List<OrdOrderCargoDto> findDtoByOrderNo(String orderNo) {
        List<OrdOrderCargo> orderCargoList = this.findByOrderNo(orderNo);

        Map<String, String> sysDictUnitBaseMap = dictService.findMapByCatalog(CommCodes.SYS_DICT_BIZ_UNIT_BASE);

        List<OrdOrderCargoDto> orderCargoDtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(orderCargoList)) {
            for (OrdOrderCargo orderCargo : orderCargoList) {
                OrdOrderCargoDto orderCargoDto = new OrdOrderCargoDto();
                EntityUtils.copyPropertiesIgnoreNull(orderCargo, orderCargoDto);
                orderCargoDto.setGoodsUnitName(sysDictUnitBaseMap.get(orderCargo.getGoodsUnit()));
                orderCargoDtoList.add(orderCargoDto);
            }
        }
        return orderCargoDtoList;
    }

    @Override
    public Map<String, List<OrdOrderCargoDto>> findDtosByOrderNos(List<String> orderNos) {
        List<OrdOrderCargo> cargoList = findByOrderNos(orderNos);
        Map<String, List<OrdOrderCargoDto>> resultMap = new HashedMap();
        if (null != cargoList && !cargoList.isEmpty()) {
            Map<String, String> sysDictUnitBaseMap = dictService.findMapByCatalog(CommCodes.SYS_DICT_BIZ_UNIT_BASE);
            for (OrdOrderCargo cargo : cargoList) {
                OrdOrderCargoDto orderCargoDto = new OrdOrderCargoDto();
                EntityUtils.copyPropertiesIgnoreNull(cargo, orderCargoDto);
                orderCargoDto.setGoodsUnitName(sysDictUnitBaseMap.get(cargo.getGoodsUnit()));
                if (resultMap.containsKey(cargo.getOrderNo())) {

                    resultMap.get(cargo.getOrderNo()).add(orderCargoDto);
                } else {
                    //map中还没有这个
                    List<OrdOrderCargoDto> dtos = Lists.newArrayList();
                    dtos.add(orderCargoDto);
                    resultMap.put(cargo.getOrderNo(), dtos);
                }

            }
        }
        return resultMap;
    }

    @Override
    public void updateOrderNoByOrderNo(String oldOrderNo, String newOrderNo) {
        if (StringUtils.isEmpty(oldOrderNo) || StringUtils.isEmpty(newOrderNo)) {
            throw Exceptions.bizException(com.sz.biz.logistics.constants.ErrorCodes.ERROR_COMMON, "提交订单异常");
        }
        ParamData pd = new ParamData();
        pd.put("newOrderNo", newOrderNo);
        pd.put("oldOrderNo", oldOrderNo);
        dao.update(getSqlName("updateOrderNoByOrderNo"), pd);
    }


    /**
     * 根据订单号、产品的uid、货物明细的集合，对货物明细进行保存
     *
     * @param orderNo           订单号
     * @param productUid        产品的uid
     * @param orderCargoDtoList 货物明细的dto集合
     */
    public void saveCargoDtos(String orderNo, String productUid, List<OrdOrderCargoDto> orderCargoDtoList) {
        this.deleteByOrderNo(orderNo);
        //、保存订单对应的货物信息
        String currencyCode = productService.getProductCurrencyByUid(productUid);
        List<OrdOrderCargo> orderCargoList = new ArrayList<>();
        for (OrdOrderCargoDto orderCargoDto : orderCargoDtoList) {
            OrdOrderCargo orderCargo = new OrdOrderCargo();
            EntityUtils.copyPropertiesIgnoreNull(orderCargoDto, orderCargo);
            orderCargo.setOrderNo(orderNo);
            orderCargo.setTradingCurrency(currencyCode);
            orderCargoList.add(orderCargo);
        }
        this.batchSave(orderCargoList);
    }
}
